package com.ybkj.daijia.api.member.v4;

import com.ybkj.daijia.Setting;
import com.ybkj.daijia.serverUtils.SettingUtils;
import com.ybkj.daijia.WxSetting;
import com.ybkj.daijia.api.beatpay.utils.BestPayCreateOrder;
import com.ybkj.daijia.api.beatpay.utils.BestPayOrderModel;
import com.ybkj.daijia.api.beatpay.utils.CryptTool;
import com.ybkj.daijia.api.member.ErrorConstant;
import com.ybkj.daijia.api.member.SecurityUtils;
import com.ybkj.daijia.api.member.alipay.config.AlipayConfig;
import com.ybkj.daijia.api.member.alipay.sign.MemberOrderSign;
import com.ybkj.daijia.api.member.alipay.sign.RSA;
import com.ybkj.daijia.api.member.alipay.util.AlipayNotify;
import com.ybkj.daijia.api.member.transport.ResultTransport;
import com.ybkj.daijia.api.unionpay.AcpService;
import com.ybkj.daijia.api.unionpay.DemoBase;
import com.ybkj.daijia.api.unionpay.LogUtil;
import com.ybkj.daijia.api.unionpay.SDKConfig;
import com.ybkj.daijia.api.unionpay.SDKConstants;
import com.ybkj.daijia.api.weixin.tenpayv3.Configuration;
import com.ybkj.daijia.api.weixin.tenpayv3.GetWxOrderno;
import com.ybkj.daijia.api.weixin.tenpayv3.RequestHandler;
import com.ybkj.daijia.api.weixin.tenpayv3.Sha1Util;
import com.ybkj.daijia.api.weixin.tenpayv3.TenpayUtil;
import com.ybkj.daijia.common.Result;
import com.ybkj.daijia.server.event.model.gasstation.GasRebateEvent;
import com.ybkj.daijia.server.gasstation.Discount;
import com.ybkj.daijia.server.gasstation.GasStation;
import com.ybkj.daijia.server.gasstation.Order;
import com.ybkj.daijia.server.gasstation.OrderTemp;
import com.ybkj.daijia.server.mc.Enterprise;
import com.ybkj.daijia.server.mc.Passenger;
import com.ybkj.daijia.server.sales.Coupon;
import com.ybkj.daijia.server.sales.CouponRule;
import com.ybkj.daijia.server.sales.CouponRule.CouponType;
import com.ybkj.daijia.server.service.CouponService;
import com.ybkj.daijia.server.service.GasDiscountService;
import com.ybkj.daijia.server.service.GasStationService;
import com.ybkj.daijia.server.service.MemberService;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.net.URLEncoder;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.TreeMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.jdom2.Document;
import org.jdom2.Element;
import org.jdom2.input.SAXBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller("GasStationProcessControllerV4")
@RequestMapping(value = "passenger/api/rest/v4/gasstation")
public class GasStationProcessController {

    private static final Logger logger = LoggerFactory.getLogger(GasStationProcessController.class);

    @Autowired
    private SettingUtils settingUtils;
    @Autowired
    private GasStationService gasStationService;
    @Autowired
    private MemberService memberService;
    @Autowired
    private CouponService couponService;
    @Autowired
    private GasDiscountService gasDiscountService;
    @Autowired
    private ApplicationEventMulticaster applicationEventMulticaster;

    /**
     * 获取请求参数中所有的信息
     *
     * @param request
     * @return
     */
    public static Map<String, String> getAllRequestParam(final HttpServletRequest request) {
        Map<String, String> res = new HashMap<String, String>();
        Enumeration<?> temp = request.getParameterNames();
        if (null != temp) {
            while (temp.hasMoreElements()) {
                String en = (String) temp.nextElement();
                String value = request.getParameter(en);
                res.put(en, value);
                // 在报文上送时，如果字段的值为空，则不上送<下面的处理为在获取所有参数数据时，判断若值为空，则删除这个字段>
                if (null == res.get(en) || "".equals(res.get(en))) {
                    res.remove(en);
                }
            }
        }
        return res;
    }

    /**
     * 查询加油站/优惠券
     *
     * @param passengerId  客户id
     * @param gasStationId 加油站id
     * @param appKey       系统key
     */
    @ResponseBody
    @RequestMapping(value = "queryGasStation", method = RequestMethod.GET)
    public ResultTransport queryGasStation(
        @RequestParam(required = true, value = "passengerId") Long passengerId,
        @RequestParam(required = true, value = "gasStationId") Long gasStationId, String appKey,
        String token, String timestamp) {

        logger.info("recv passengerId:{},gasStationId:{},appKey:{},token:{},timestamp:{}",
            passengerId, gasStationId, appKey, token, timestamp);

        if (passengerId == null || gasStationId == null
            || SecurityUtils.isBlank(appKey, token, timestamp)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        List<String> params = new LinkedList<String>();
        params.add(String.valueOf(passengerId));
        params.add(String.valueOf(gasStationId));
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        try {
            Passenger passenger = memberService.findOnePassenger(passengerId);

            if (passenger == null) {
                return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
            }

            Discount discount = null;

            Long grade_id = passenger.getGrade_id();
            if (null != grade_id) {
                discount = gasDiscountService.queryOneGrade(grade_id, gasStationId);
            }

            List<Coupon> coupons = couponService
                .listByPassenger(passengerId, CouponType.gasstation, null, null);
            List<Map<String, Object>> couponMapList = new ArrayList<Map<String, Object>>();

            if (!CollectionUtils.isEmpty(coupons)) {
                for (Coupon coupon : coupons) {
                    CouponRule rule = coupon.getCouponRule();
                    Map<String, Object> couponMap = new HashMap<String, Object>();
                    couponMap.put("couponId", coupon.getId());
                    couponMap.put("couponType", rule.getType());
                    couponMap.put("couponMoney", rule.getMoney());
                    couponMap.put("couponDiscount", rule.getDiscount());
                    couponMap.put("couponCode", coupon.getCode());
                    couponMap.put("couponTitle", rule.getTitle());
                    couponMap.put("startTime", rule.getStart().getTime());
                    if (null != rule.getEnd()) {
                        couponMap.put("endTime", rule.getEnd().getTime());
                    } else {
                        couponMap.put("endTime", null);
                    }
                    couponMapList.add(couponMap);
                }
            }

            Map<String, Object> map = new HashMap<String, Object>();

            map.put("coupons", couponMapList);

            if (null != discount) {
                map.put("discount", discount.getDiscount());
            } else {
                map.put("discount", 0);
            }
            if (passenger.getType() == Passenger.TYPE_PASSENGER) {
                map.put(
                    "balance",
                    passenger.getDrawMoney().add(passenger.getNodrawMoney())
                        .setScale(2, BigDecimal.ROUND_HALF_UP));
            } else if (passenger.getType() == Passenger.TYPE_ENTERPRISE) {
                Enterprise enterprise = memberService
                    .findOneEnterprise(passenger.getEnterprise_id());
                map.put(
                    "balance",
                    enterprise.getDrawMoney().add(enterprise.getNodrawMoney())
                        .setScale(2, BigDecimal.ROUND_HALF_UP));
            }

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);

            instance.setData(map);

            return instance;
        } catch (Exception e) {
            logger.error("api v4up queryGasStation error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }
    }

    @RequestMapping(value = "paymentOrder", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport paymentOrder(
        @RequestParam(required = true, value = "passengerId") Long passengerId,
        @RequestParam(required = true, value = "gsId") Long gsId,
        @RequestParam(required = true, value = "gasNum") String gasNum,
        @RequestParam(required = false, value = "compressorGun") String compressorGun,
        @RequestParam(required = true, value = "money") BigDecimal money,
        @RequestParam(required = true, value = "realMoney") BigDecimal realMoney,
        @RequestParam(required = true, value = "discountMoney") BigDecimal discountMoney,
        @RequestParam(required = false, value = "couponId") Long couponId,
        @RequestParam(required = true, value = "payType") String payType, String appKey,
        String token, String timestamp) {

        logger
            .error(
                "recv gsId:{},gasNum{},compressorGun{},money{},realMoney{},discountMoney{},couponId{},payType{}",
                gsId, gasNum, compressorGun, money, realMoney, discountMoney, couponId, payType);

        List<String> params = new LinkedList<String>();
        params.add(String.valueOf(passengerId));
        params.add(String.valueOf(gsId));
        params.add(String.valueOf(gasNum));
        params.add(String.valueOf(money));
        params.add(String.valueOf(realMoney));
        params.add(String.valueOf(discountMoney));
        params.add(String.valueOf(payType));
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        if (!"balance".equals(payType)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        GasStation gasStation = gasStationService.queryById(gsId);
        if (null == gasStation) {
            return ResultTransport.getErrorBy(ErrorConstant.GASSTATION_NOT_EXISTS);
        }

        Passenger passenger = memberService.findOnePassenger(passengerId);
        if (null == passenger) {
            return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
        }

        Order lastOrder = gasStationService.findLastOrderByPassenger(passenger.getId());
        if (null != lastOrder) {
            if ((System.currentTimeMillis() - lastOrder.getCreated().getTime()) < 10 * 1000) {
                return ResultTransport.getErrorBy(ErrorConstant.SERVER_BUSY);
            }
        }

        if ("balance".equals(payType)) {// 余额支付
            if (passenger.getType().equals(Passenger.TYPE_PASSENGER)) {
                BigDecimal shengyuMoney = BigDecimal.ZERO;
                shengyuMoney = shengyuMoney.add(passenger.getNodrawMoney());
                if (passenger.getDrawMoney().doubleValue() > 0) {
                    shengyuMoney = shengyuMoney.add(passenger.getDrawMoney());
                }
                if (shengyuMoney.doubleValue() < realMoney.doubleValue()) {
                    return ResultTransport
                        .getErrorBy(ErrorConstant.PASSENGER_CANTNOT_APPLY_ENTERPRISE);
                }
            } else if (passenger.getType().equals(Passenger.TYPE_ENTERPRISE)) {
                Enterprise enterprise = memberService
                    .findOneEnterprise(passenger.getEnterprise_id());
                BigDecimal shengyuMoney = BigDecimal.ZERO;
                shengyuMoney = shengyuMoney.add(enterprise.getNodrawMoney());
                if (enterprise.getDrawMoney().doubleValue() > 0) {
                    shengyuMoney = shengyuMoney.add(enterprise.getDrawMoney());
                }
                if (shengyuMoney.doubleValue() < realMoney.doubleValue()) {
                    return ResultTransport.getErrorBy(ErrorConstant.MEMBER_MONEY_NOT_ENOUGH);
                }
            }
        }

        Order order = new Order();
        order.setDiscountMoney(discountMoney);
        order.setGsId(gasStation.getId());
        order.setGsName(gasStation.getName());
        order.setGsServiceNo(gasStation.getServiceNo());
        order.setGasNum(gasNum);
        order.setCompressorGun(compressorGun);
        order.setMoney(money);
        order.setPassengerId(passenger.getId());
        order.setPassengerName(passenger.getName());
        order.setPassengerPhone(passenger.getPhone());
        order.setPayType(Order.PayType.valueOf(payType));
        order.setRealMoney(realMoney);
        order.setCouponId(couponId);

        try {
            Result<Order> result = gasStationService.paymentOrder(order, passenger);

            if (result.isSuccess()) {

                if (null != passenger) {
                    GasRebateEvent gasRebateEvent = new GasRebateEvent(passenger,
                        result.getResult(),
                        order.getRealMoney());
                    applicationEventMulticaster.multicastEvent(gasRebateEvent);
                }

                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
                instance.setData(result.getResult());
                return instance;
            } else {
                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
                return instance;
            }
        } catch (Exception e) {
            e.printStackTrace();
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
            return instance;
        }
    }

    /**
     * 微信V5查询加油站/优惠券
     *
     * @param passengerId  客户id
     * @param gasStationId 加油站id
     * @param appKey       系统key
     */
    @ResponseBody
    @RequestMapping(value = "queryGasStationV5", method = RequestMethod.GET)
    public ResultTransport queryGasStationV5(
        @RequestParam(required = true, value = "passengerId") Long passengerId,
        @RequestParam(required = true, value = "gasStationId") Long gasStationId, String appKey,
        String timestamp) {

        logger.info("recv passengerId:{},gasStationId:{},appKey:{},token:{},timestamp:{}",
            passengerId, gasStationId, appKey, timestamp);

        if (passengerId == null || gasStationId == null || null == appKey || appKey.isEmpty()
            || null == timestamp || timestamp.isEmpty()) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        try {
            Passenger passenger = memberService.findOnePassenger(passengerId);

            if (passenger == null) {
                return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
            }

            Discount discount = null;

            Long grade_id = passenger.getGrade_id();
            if (null != grade_id) {
                discount = gasDiscountService.queryOneGrade(grade_id, gasStationId);
            }

            List<Coupon> coupons = couponService
                .listByPassenger(passengerId, CouponType.gasstation, null, null);
            List<Map<String, Object>> couponMapList = new ArrayList<Map<String, Object>>();

            if (!CollectionUtils.isEmpty(coupons)) {
                for (Coupon coupon : coupons) {
                    CouponRule rule = coupon.getCouponRule();
                    Map<String, Object> couponMap = new HashMap<String, Object>();
                    couponMap.put("couponId", coupon.getId());
                    couponMap.put("couponType", rule.getType());
                    couponMap.put("couponMoney", rule.getMoney());
                    couponMap.put("couponDiscount", rule.getDiscount());
                    couponMap.put("couponCode", coupon.getCode());
                    couponMap.put("couponTitle", rule.getTitle());
                    couponMap.put("startTime", rule.getStart().getTime());
                    if (null != rule.getEnd()) {
                        couponMap.put("endTime", rule.getEnd().getTime());
                    } else {
                        couponMap.put("endTime", null);
                    }
                    couponMapList.add(couponMap);
                }
            }

            Map<String, Object> map = new HashMap<String, Object>();

            map.put("coupons", couponMapList);

            if (null != discount) {
                map.put("discount", discount.getDiscount());
            } else {
                map.put("discount", 0);
            }
            if (passenger.getType() == Passenger.TYPE_PASSENGER) {
                map.put(
                    "balance",
                    passenger.getDrawMoney().add(passenger.getNodrawMoney())
                        .setScale(2, BigDecimal.ROUND_HALF_UP));
            } else if (passenger.getType() == Passenger.TYPE_ENTERPRISE) {
                Enterprise enterprise = memberService
                    .findOneEnterprise(passenger.getEnterprise_id());
                map.put(
                    "balance",
                    enterprise.getDrawMoney().add(enterprise.getNodrawMoney())
                        .setScale(2, BigDecimal.ROUND_HALF_UP));
            }

            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);

            instance.setData(map);

            return instance;
        } catch (Exception e) {
            logger.error("api v4up queryGasStation error: {}", e);
            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
        }
    }

    /**
     * 微信V5加油站余额支付
     *
     * @param passengerId   客户Id
     * @param gsId          加油站Id
     * @param gasNum        油号
     * @param compressorGun 加油枪
     * @param money         加油金额
     * @param realMoney     实际支付
     * @param discountMoney 平台折扣
     * @param couponId      优惠券Id
     * @param payType       支付类型
     * @param appKey        系统Key
     * @param timestamp     时间戳
     * @return
     */
    @RequestMapping(value = "paymentOrderV5", method = RequestMethod.POST)
    public @ResponseBody
    ResultTransport paymentOrderV5(
        @RequestParam(required = true, value = "passengerId") Long passengerId,
        @RequestParam(required = true, value = "gsId") Long gsId,
        @RequestParam(required = true, value = "gasNum") String gasNum,
        @RequestParam(required = false, value = "compressorGun") String compressorGun,
        @RequestParam(required = true, value = "money") BigDecimal money,
        @RequestParam(required = true, value = "realMoney") BigDecimal realMoney,
        @RequestParam(required = true, value = "discountMoney") BigDecimal discountMoney,
        @RequestParam(required = false, value = "couponId") Long couponId,
        @RequestParam(required = true, value = "payType") String payType, String appKey,
        String timestamp) {

        logger
            .error(
                "recv gsId:{},gasNum{},compressorGun{},money{},realMoney{},discountMoney{},couponId{},payType{}",
                gsId, gasNum, compressorGun, money, realMoney, discountMoney, couponId, payType);

        if (!"balance".equals(payType)) {
            return ResultTransport.getErrorBy(ErrorConstant.PARAM_ERROR);
        }

        GasStation gasStation = gasStationService.queryById(gsId);
        if (null == gasStation) {
            return ResultTransport.getErrorBy(ErrorConstant.GASSTATION_NOT_EXISTS);
        }

        Passenger passenger = memberService.findOnePassenger(passengerId);
        if (null == passenger) {
            return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
        }

        Order lastOrder = gasStationService.findLastOrderByPassenger(passenger.getId());
        if (null != lastOrder) {
            if ((System.currentTimeMillis() - lastOrder.getCreated().getTime()) < 10 * 1000) {
                return ResultTransport.getErrorBy(ErrorConstant.SERVER_BUSY);
            }
        }

        if ("balance".equals(payType)) {// 余额支付
            if (passenger.getType().equals(Passenger.TYPE_PASSENGER)) {
                BigDecimal shengyuMoney = BigDecimal.ZERO;
                shengyuMoney = shengyuMoney.add(passenger.getNodrawMoney());
                if (passenger.getDrawMoney().doubleValue() > 0) {
                    shengyuMoney = shengyuMoney.add(passenger.getDrawMoney());
                }
                if (shengyuMoney.doubleValue() < realMoney.doubleValue()) {
                    return ResultTransport
                        .getErrorBy(ErrorConstant.PASSENGER_CANTNOT_APPLY_ENTERPRISE);
                }
            } else if (passenger.getType().equals(Passenger.TYPE_ENTERPRISE)) {
                Enterprise enterprise = memberService
                    .findOneEnterprise(passenger.getEnterprise_id());
                BigDecimal shengyuMoney = BigDecimal.ZERO;
                shengyuMoney = shengyuMoney.add(enterprise.getNodrawMoney());
                if (enterprise.getDrawMoney().doubleValue() > 0) {
                    shengyuMoney = shengyuMoney.add(enterprise.getDrawMoney());
                }
                if (shengyuMoney.doubleValue() < realMoney.doubleValue()) {
                    return ResultTransport.getErrorBy(ErrorConstant.MEMBER_MONEY_NOT_ENOUGH);
                }
            }
        }

        Order order = new Order();
        order.setDiscountMoney(discountMoney);
        order.setGsId(gasStation.getId());
        order.setGsName(gasStation.getName());
        order.setGsServiceNo(gasStation.getServiceNo());
        order.setGasNum(gasNum);
        order.setCompressorGun(compressorGun);
        order.setMoney(money);
        order.setPassengerId(passenger.getId());
        order.setPassengerName(passenger.getName());
        order.setPassengerPhone(passenger.getPhone());
        order.setPayType(Order.PayType.valueOf(payType));
        order.setRealMoney(realMoney);
        order.setCouponId(couponId);

        try {
            Result<Order> result = gasStationService.paymentOrder(order, passenger);

            if (result.isSuccess()) {

                if (null != passenger) {
                    GasRebateEvent gasRebateEvent = new GasRebateEvent(passenger,
                        result.getResult(),
                        order.getRealMoney());
                    try {
                        applicationEventMulticaster.multicastEvent(gasRebateEvent);
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }

                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
                instance.setData(result.getResult());
                return instance;
            } else {
                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
                return instance;
            }
        } catch (Exception e) {
            e.printStackTrace();
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
            return instance;
        }
    }

    @RequestMapping(value = "alipay/prepayOrder")
    public synchronized @ResponseBody
    ResultTransport alipayPrepayOrder(
        @RequestParam(required = true, value = "passengerId") Long passengerId,
        @RequestParam(required = true, value = "gsId") Long gsId,
        @RequestParam(required = true, value = "gasNum") String gasNum,
        @RequestParam(required = false, value = "compressorGun") String compressorGun,
        @RequestParam(required = true, value = "money") BigDecimal money,
        @RequestParam(required = true, value = "realMoney") BigDecimal realMoney,
        @RequestParam(required = true, value = "discountMoney") BigDecimal discountMoney,
        @RequestParam(required = false, value = "couponId") Long couponId, String appKey,
        String token, String timestamp, HttpServletResponse response, HttpServletRequest request) {

        List<String> params = new LinkedList<String>();
        params.add(String.valueOf(passengerId));
        params.add(String.valueOf(gsId));
        params.add(String.valueOf(gasNum));
        params.add(String.valueOf(money));
        params.add(String.valueOf(realMoney));
        params.add(String.valueOf(discountMoney));
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        GasStation gasStation = gasStationService.queryById(gsId);
        if (null == gasStation) {
            return ResultTransport.getErrorBy(ErrorConstant.GASSTATION_NOT_EXISTS);
        }

        Passenger passenger = memberService.findOnePassenger(passengerId);
        if (null == passenger) {
            return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
        }

        try {

            OrderTemp orderTemp = new OrderTemp();
            orderTemp.setDiscountMoney(discountMoney);
            orderTemp.setGsId(gasStation.getId());
            orderTemp.setGsName(gasStation.getName());
            orderTemp.setGsServiceNo(gasStation.getServiceNo());
            orderTemp.setGasNum(gasNum);
            orderTemp.setCompressorGun(compressorGun);
            orderTemp.setMoney(money);
            orderTemp.setPassengerId(passenger.getId());
            orderTemp.setPassengerName(passenger.getName());
            orderTemp.setPassengerPhone(passenger.getPhone());
            orderTemp.setPayType(OrderTemp.PayType.alipay);
            orderTemp.setRealMoney(realMoney);
            orderTemp.setCouponId(couponId);

            Result<OrderTemp> result = gasStationService.paymentOrderTemp(orderTemp);

            if (result.isSuccess()) {
                Setting setting = settingUtils.get();

                Map<String, Object> map = new HashMap<String, Object>();
                map.put("PartnerID", setting.getAlipayPartnerID());
                map.put("SellerID", setting.getAlipaySellerID());
                map.put("PartnerPrivKey", setting.getAlipayPartnerPrivKey());
                map.put("PartnerPublicKey", AlipayConfig.ali_public_key);
                map.put("tradeNO", "jyz_af_" + result.getResult().getId());
                map.put("productName", "加油订单付费");
                map.put("productDescription", "加油订单付费");
                map.put("amount", realMoney);
                map.put("notifyURL", setting.getWebUrl()
                    + "/passenger/api/rest/v4/gasstation/alipay/payOrderNotify");
                String content = MemberOrderSign.sign(map);
                String sign = RSA.sign(content, setting.getAlipayPartnerPrivKey(), "utf-8");
                sign = URLEncoder.encode(sign, "utf-8");
                String url = content + "&sign=\"" + sign + "\"&sign_type=\"RSA\"";

                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
                instance.setData(url);
                return instance;
            } else {
                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
                return instance;
            }

        } catch (Exception e) {
            e.printStackTrace();
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
            return instance;
        }
    }

    // 支付宝支付后的接口
    @RequestMapping(value = "alipay/payOrderNotify")
    public synchronized @ResponseBody
    String alipayPayOrderNotify(HttpServletResponse response,
        HttpServletRequest request) throws UnsupportedEncodingException {
        Setting setting = settingUtils.get();
        // 获取支付宝POST过来反馈信息
        Map<String, String> params = new HashMap<String, String>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext(); ) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr =
                    (i == values.length - 1) ? valueStr + values[i] : valueStr + values[i] + ",";
            }

            // 乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            // valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
            params.put(name, valueStr);
        }

        // 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以下仅供参考)//
        // 商户订单号
        String out_trade_no = new String(
            request.getParameter("out_trade_no").getBytes("ISO-8859-1"),
            "UTF-8");
        // 支付宝交易号
        String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),
            "UTF-8");
        // 交易状态
        String trade_status = new String(
            request.getParameter("trade_status").getBytes("ISO-8859-1"),
            "UTF-8");
        // 获取支付宝的通知返回参数，可参考技术文档中页面跳转同步通知参数列表(以上仅供参考)//
        logger.info("商户订单号：" + out_trade_no);
        logger.error("交易号：" + trade_no + "交易状态：" + trade_status);
        if (AlipayNotify.verify(params, setting)) {// 验证成功
            if (trade_status.equals("TRADE_FINISHED")) {
                Long orderTempId = Long.valueOf(out_trade_no.split("_")[2]);
                OrderTemp orderTemp = gasStationService.findOneOrderTemp(orderTempId);
                if (orderTemp.getStatus().equals(OrderTemp.status_finish)) {
                    return "success";
                }

                Order order = new Order();
                order.setDiscountMoney(orderTemp.getDiscountMoney());
                order.setGsId(orderTemp.getGsId());
                order.setGsName(orderTemp.getGsName());
                order.setGsServiceNo(orderTemp.getGsServiceNo());
                order.setGasNum(orderTemp.getGasNum());
                order.setCompressorGun(orderTemp.getCompressorGun());
                order.setMoney(orderTemp.getMoney());
                order.setPassengerId(orderTemp.getPassengerId());
                order.setPassengerName(orderTemp.getPassengerName());
                order.setPassengerPhone(orderTemp.getPassengerPhone());
                order.setPayType(Order.PayType.alipay);
                order.setRealMoney(orderTemp.getRealMoney());
                order.setCouponId(orderTemp.getCouponId());

                Passenger passenger = memberService.findOnePassenger(orderTemp.getPassengerId());

                Result<Order> result = gasStationService.paymentOrder(order, passenger);

                if (result.isSuccess()) {

                    if (null != passenger) {
                        GasRebateEvent gasRebateEvent = new GasRebateEvent(passenger,
                            result.getResult(),
                            order.getRealMoney());
                        applicationEventMulticaster.multicastEvent(gasRebateEvent);
                    }

                    Result<OrderTemp> result2 = gasStationService.orderTempTreament(orderTempId);

                    if (result2.isSuccess()) {
                        return "success";
                    } else {
                        return "fail";
                    }

                } else {
                    return "fail";
                }

            } else if (trade_status.equals("TRADE_SUCCESS")) {
                Long orderTempId = Long.valueOf(out_trade_no.split("_")[2]);
                OrderTemp orderTemp = gasStationService.findOneOrderTemp(orderTempId);
                if (orderTemp.getStatus().equals(OrderTemp.status_finish)) {
                    return "success";
                }

                Order order = new Order();
                order.setDiscountMoney(orderTemp.getDiscountMoney());
                order.setGsId(orderTemp.getGsId());
                order.setGsName(orderTemp.getGsName());
                order.setGsServiceNo(orderTemp.getGsServiceNo());
                order.setGasNum(orderTemp.getGasNum());
                order.setCompressorGun(orderTemp.getCompressorGun());
                order.setMoney(orderTemp.getMoney());
                order.setPassengerId(orderTemp.getPassengerId());
                order.setPassengerName(orderTemp.getPassengerName());
                order.setPassengerPhone(orderTemp.getPassengerPhone());
                order.setPayType(Order.PayType.alipay);
                order.setRealMoney(orderTemp.getRealMoney());
                order.setCouponId(orderTemp.getCouponId());

                Passenger passenger = memberService.findOnePassenger(orderTemp.getPassengerId());

                Result<Order> result = gasStationService.paymentOrder(order, passenger);

                if (result.isSuccess()) {

                    if (null != passenger) {
                        GasRebateEvent gasRebateEvent = new GasRebateEvent(passenger,
                            result.getResult(),
                            order.getRealMoney());
                        applicationEventMulticaster.multicastEvent(gasRebateEvent);
                    }

                    Result<OrderTemp> result2 = gasStationService.orderTempTreament(orderTempId);

                    if (result2.isSuccess()) {
                        return "success";
                    } else {
                        return "fail";
                    }

                } else {
                    return "fail";
                }

            }
            return "fail";
        } else {
            return "fail";
        }

    }

    // 微信支付前接口
    @RequestMapping(value = "wx/prepayOrder")
    public synchronized @ResponseBody
    ResultTransport wxPrepayOrder(
        @RequestParam(required = true, value = "passengerId") Long passengerId,
        @RequestParam(required = true, value = "gsId") Long gsId,
        @RequestParam(required = true, value = "gasNum") String gasNum,
        @RequestParam(required = false, value = "compressorGun") String compressorGun,
        @RequestParam(required = true, value = "money") BigDecimal money,
        @RequestParam(required = true, value = "realMoney") BigDecimal realMoney,
        @RequestParam(required = true, value = "discountMoney") BigDecimal discountMoney,
        @RequestParam(required = false, value = "couponId") Long couponId, String appKey,
        String token, String timestamp, HttpServletResponse response, HttpServletRequest request) {

        List<String> params = new LinkedList<String>();
        params.add(String.valueOf(passengerId));
        params.add(String.valueOf(gsId));
        params.add(String.valueOf(gasNum));
        params.add(String.valueOf(money));
        params.add(String.valueOf(realMoney));
        params.add(String.valueOf(discountMoney));
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        GasStation gasStation = gasStationService.queryById(gsId);
        if (null == gasStation) {
            return ResultTransport.getErrorBy(ErrorConstant.GASSTATION_NOT_EXISTS);
        }

        Passenger passenger = memberService.findOnePassenger(passengerId);
        if (null == passenger) {
            return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
        }

        try {

            OrderTemp orderTemp = new OrderTemp();
            orderTemp.setDiscountMoney(discountMoney);
            orderTemp.setGsId(gasStation.getId());
            orderTemp.setGsName(gasStation.getName());
            orderTemp.setGsServiceNo(gasStation.getServiceNo());
            orderTemp.setGasNum(gasNum);
            orderTemp.setCompressorGun(compressorGun);
            orderTemp.setMoney(money);
            orderTemp.setPassengerId(passenger.getId());
            orderTemp.setPassengerName(passenger.getName());
            orderTemp.setPassengerPhone(passenger.getPhone());
            orderTemp.setPayType(OrderTemp.PayType.weixin);
            orderTemp.setRealMoney(realMoney);
            orderTemp.setCouponId(couponId);

            Result<OrderTemp> result = gasStationService.paymentOrderTemp(orderTemp);

            if (result.isSuccess()) {
                Setting setting = settingUtils.get();
                String createOrderURL = Configuration.createOrderURL;

                // 商户相关资料
                String appid = setting.getWxAppID();
                String appsecret = setting.getWxAppSecret();
                String partner = setting.getWxPartnerID();
                String partnerkey = setting.getWxPartnerKey();

                // 获取openId后调用统一支付接口https://api.mch.weixin.qq.com/pay/unifiedorder
                String currTime = TenpayUtil.getCurrTime();
                // 8位日期
                String strTime = currTime.substring(8, currTime.length());
                // 四位随机数
                String strRandom = TenpayUtil.buildRandom(6) + "";
                // 10位序列号,可以自行调整。
                String strReq = strTime + strRandom;
                // 商户号
                String mch_id = partner;
                // 随机数
                String nonce_str = strReq;
                // 商品描述
                String body = "加油订单付费";
                // 商户订单号
                String out_trade_no = "jyz_af_" + result.getResult().getId();
                // 总金额以分为单位，不带小数点
                String total_fee = String
                    .valueOf(realMoney.multiply(new BigDecimal(100)).intValue());
                // 订单生成的机器 IP
                String spbill_create_ip = request.getRemoteAddr();

                // 这里notify_url是 支付完成后微信发给该链接信息，可以判断会员是否支付成功，改变订单状态等。
                String notify_url = setting.getWebUrl()
                    + "/passenger/api/rest/v4/gasstation/wx/payOrderNotify";

                String trade_type = "APP";

                SortedMap<String, String> packageParams = new TreeMap<String, String>();
                packageParams.put("appid", appid);
                packageParams.put("mch_id", mch_id);
                packageParams.put("nonce_str", nonce_str);
                packageParams.put("body", body);
                packageParams.put("out_trade_no", out_trade_no);

                // 这里写的金额为1 分到时修改
                // packageParams.put("total_fee", "1");
                packageParams.put("total_fee", total_fee);
                packageParams.put("spbill_create_ip", spbill_create_ip);
                packageParams.put("notify_url", notify_url);
                packageParams.put("trade_type", trade_type);

                RequestHandler reqHandler = new RequestHandler(request, response);
                reqHandler.init(appid, appsecret, partnerkey);

                String sign = reqHandler.createSign(packageParams);
                String xml =
                    "<xml>" + "<appid>" + appid + "</appid>" + "<mch_id>" + mch_id + "</mch_id>"
                        + "<nonce_str>" + nonce_str + "</nonce_str>" + "<sign>" + sign + "</sign>"
                        + "<body><![CDATA[" + body + "]]></body>" + "<out_trade_no>"
                        + out_trade_no
                        + "</out_trade_no>"
                        +
                        // "<total_fee>"+1+"</total_fee>"+
                        "<total_fee>" + total_fee + "</total_fee>" + "<spbill_create_ip>"
                        + spbill_create_ip
                        + "</spbill_create_ip>" + "<notify_url>" + notify_url + "</notify_url>"
                        + "<trade_type>" + trade_type + "</trade_type>" + "</xml>";

                String prepay_id = "";
                try {
                    prepay_id = new GetWxOrderno().getPayNo(createOrderURL, xml);
                    if (prepay_id.equals("")) {
                        logger.error("统一支付接口获取预支付订单出错");
                    }
                } catch (Exception e1) {
                    e1.printStackTrace();
                }

                SortedMap<String, String> finalpackage = new TreeMap<String, String>();
                finalpackage.put("appid", appid);
                finalpackage.put("partnerid", partner);
                finalpackage.put("prepayid", prepay_id);
                finalpackage.put("package", "Sign=WXPay");
                finalpackage.put("noncestr", nonce_str);
                finalpackage.put("timestamp", Sha1Util.getTimeStamp());
                String finalsign = reqHandler.createSign(finalpackage);
                finalpackage.put("sign", finalsign);

                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
                instance.setData(finalpackage);
                return instance;
            } else {
                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
                return instance;
            }
        } catch (Exception e) {
            e.printStackTrace();
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
            return instance;
        }

    }

    /**
     * 微信加油站V5支付
     *
     * @param passengerId   客户Id
     * @param gsId          加油站Id
     * @param gasNum        油号
     * @param compressorGun 加油枪
     * @param money         加油金额
     * @param realMoney     实际支付
     * @param discountMoney 平台打折
     * @param couponId      优惠券Id
     * @param appKey        系统Key
     * @param timestamp     时间戳
     * @return
     */
    @RequestMapping(value = "wx/prepayOrderV5")
    public synchronized @ResponseBody
    ResultTransport wxPrepayOrderV5(
        @RequestParam(required = true, value = "openId") String openId,
        @RequestParam(required = true, value = "passengerId") Long passengerId,
        @RequestParam(required = true, value = "gsId") Long gsId,
        @RequestParam(required = true, value = "gasNum") String gasNum,
        @RequestParam(required = false, value = "compressorGun") String compressorGun,
        @RequestParam(required = true, value = "money") BigDecimal money,
        @RequestParam(required = true, value = "realMoney") BigDecimal realMoney,
        @RequestParam(required = true, value = "discountMoney") BigDecimal discountMoney,
        @RequestParam(required = false, value = "couponId") Long couponId, String appKey,
        String timestamp, HttpServletResponse response, HttpServletRequest request) {
        GasStation gasStation = gasStationService.queryById(gsId);
        if (null == gasStation) {
            return ResultTransport.getErrorBy(ErrorConstant.GASSTATION_NOT_EXISTS);
        }
        Passenger passenger = memberService.findOnePassenger(passengerId);
        if (null == passenger) {
            return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
        }
        try {
            OrderTemp orderTemp = new OrderTemp();
            orderTemp.setDiscountMoney(discountMoney);
            orderTemp.setGsId(gasStation.getId());
            orderTemp.setGsName(gasStation.getName());
            orderTemp.setGsServiceNo(gasStation.getServiceNo());
            orderTemp.setGasNum(gasNum);
            orderTemp.setCompressorGun(compressorGun);
            orderTemp.setMoney(money);
            orderTemp.setPassengerId(passenger.getId());
            orderTemp.setPassengerName(passenger.getName());
            orderTemp.setPassengerPhone(passenger.getPhone());
            orderTemp.setPayType(OrderTemp.PayType.weixin);
            orderTemp.setRealMoney(realMoney);
            orderTemp.setCouponId(couponId);
            Result<OrderTemp> result = gasStationService.paymentOrderTemp(orderTemp);
            if (result.isSuccess()) {
                WxSetting wxSetting = settingUtils.getWx();
                Setting sysSetting = settingUtils.get();
                String createOrderURL = Configuration.createOrderURL;
                // 商户相关资料
                String appid = wxSetting.getWxAppId();
                String appsecret = wxSetting.getWxAppSecret();
                String partner = wxSetting.getWxPartnerId();
                String partnerkey = wxSetting.getWxPartnerKey();

                // 获取openId后调用统一支付接口https://api.mch.weixin.qq.com/pay/unifiedorder
                String currTime = TenpayUtil.getCurrTime();
                // 8位日期
                String strTime = currTime.substring(8, currTime.length());
                // 四位随机数
                String strRandom = TenpayUtil.buildRandom(6) + "";
                // 10位序列号,可以自行调整。
                String strReq = strTime + strRandom;
                // 商户号
                String mch_id = partner;
                // 随机数
                String nonce_str = strReq;
                // 商品描述
                String body = "加油订单付费";
                // 商户订单号
                String out_trade_no = "jyz_af_" + result.getResult().getId();
                // 总金额以分为单位，不带小数点
                String total_fee = String
                    .valueOf(realMoney.multiply(new BigDecimal(100)).intValue());
                // 订单生成的机器 IP
                String spbill_create_ip = request.getRemoteAddr();
                // 这里notify_url是 支付完成后微信发给该链接信息，可以判断会员是否支付成功，改变订单状态等。
                String notify_url = sysSetting.getWebUrl()
                    + "/passenger/api/rest/v4/gasstation/wx/payOrderNotify";

                String trade_type = "JSAPI";

                SortedMap<String, String> packageParams = new TreeMap<String, String>();
                packageParams.put("appid", appid);
                packageParams.put("mch_id", mch_id);
                packageParams.put("nonce_str", nonce_str);
                packageParams.put("body", body);
                packageParams.put("out_trade_no", out_trade_no);
                packageParams.put("total_fee", total_fee);
                packageParams.put("spbill_create_ip", spbill_create_ip);
                packageParams.put("notify_url", notify_url);
                packageParams.put("trade_type", trade_type);
                packageParams.put("openid", openId);

                RequestHandler reqHandler = new RequestHandler(request, response);
                reqHandler.init(appid, appsecret, partnerkey);

                String sign = reqHandler.createSign(packageParams);
                String xml =
                    "<xml>" + "<appid>" + appid + "</appid>" + "<mch_id>" + mch_id + "</mch_id>"
                        + "<nonce_str>" + nonce_str + "</nonce_str>" + "<sign>" + sign + "</sign>"
                        + "<body><![CDATA[" + body + "]]></body>" + "<out_trade_no>" + out_trade_no
                        + "</out_trade_no>" + "<total_fee>" + total_fee + "</total_fee>"
                        + "<spbill_create_ip>"
                        + spbill_create_ip + "</spbill_create_ip>" + "<notify_url>" + notify_url
                        + "</notify_url>" + "<trade_type>" + trade_type + "</trade_type>"
                        + "<openid>" + openId
                        + "</openid>" + "</xml>";

                String prepay_id = "";
                try {
                    prepay_id = GetWxOrderno.getPayNo(createOrderURL, xml);
                    if (prepay_id.equals("")) {
                        logger.error("统一支付接口获取预支付订单出错");
                    }
                } catch (Exception e1) {
                    e1.printStackTrace();
                }

                SortedMap<String, String> finalpackage = new TreeMap<String, String>();
                finalpackage.put("appId", appid);
                finalpackage.put("timeStamp", Sha1Util.getTimeStamp());
                finalpackage.put("nonceStr", nonce_str);
                finalpackage.put("package", "prepay_id=" + prepay_id + "");
                finalpackage.put("signType", "MD5");
                String finalsign = reqHandler.createSign(finalpackage);
                finalpackage.put("paySign", finalsign);

                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
                instance.setData(finalpackage);
                return instance;
            } else {
                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
                return instance;
            }
        } catch (Exception e) {
            e.printStackTrace();
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
            return instance;
        }

    }

    // 微信支付后接口
    @RequestMapping("wx/payOrderNotify")
    public synchronized @ResponseBody
    String wxPayOrderNotify(HttpServletResponse response,
        HttpServletRequest request) throws Exception {

        String out_trade_no = "";

        try {

            BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
            String line = null;
            StringBuilder sb = new StringBuilder();
            while ((line = br.readLine()) != null) {
                sb.append(line);
            }
            String strxml = sb.toString();

            InputStream in = new ByteArrayInputStream(strxml.getBytes());
            SAXBuilder builder = new SAXBuilder();
            Document doc = builder.build(in);
            Element root = doc.getRootElement();
            List list = root.getChildren();
            Iterator it = list.iterator();
            while (it.hasNext()) {
                Element e = (Element) it.next();
                String k = e.getName();
                if (k.equals("out_trade_no")) {
                    out_trade_no = e.getText();
                }
            }

            try {
                // 关闭流
                if (null != in) {
                    in.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            if (StringUtils.isBlank(out_trade_no)) {
                return "FAIL";
            }

            Long orderTempId = Long.valueOf(out_trade_no.split("_")[2]);

            OrderTemp orderTemp = gasStationService.findOneOrderTemp(orderTempId);
            if (orderTemp.getStatus().equals(OrderTemp.status_finish)) {
                return "SUCCESS";
            }

            Order order = new Order();
            order.setDiscountMoney(orderTemp.getDiscountMoney());
            order.setGsId(orderTemp.getGsId());
            order.setGsName(orderTemp.getGsName());
            order.setGsServiceNo(orderTemp.getGsServiceNo());
            order.setGasNum(orderTemp.getGasNum());
            order.setCompressorGun(orderTemp.getCompressorGun());
            order.setMoney(orderTemp.getMoney());
            order.setPassengerId(orderTemp.getPassengerId());
            order.setPassengerName(orderTemp.getPassengerName());
            order.setPassengerPhone(orderTemp.getPassengerPhone());
            order.setPayType(Order.PayType.weixin);
            order.setRealMoney(orderTemp.getRealMoney());
            order.setCouponId(orderTemp.getCouponId());

            Passenger passenger = memberService.findOnePassenger(orderTemp.getPassengerId());

            Result<Order> result = gasStationService.paymentOrder(order, passenger);

            if (result.isSuccess()) {

                if (null != passenger) {
                    GasRebateEvent gasRebateEvent = new GasRebateEvent(passenger,
                        result.getResult(),
                        order.getRealMoney());
                    applicationEventMulticaster.multicastEvent(gasRebateEvent);
                }

                Result<OrderTemp> result2 = gasStationService.orderTempTreament(orderTempId);

                if (result2.isSuccess()) {
                    return "SUCCESS";
                } else {
                    return "FAIL";
                }

            } else {
                return "FAIL";
            }

        } catch (Exception e) {
            e.printStackTrace();
            return "FAIL";
        }

    }

    /**
     * 银联支付接口
     */
    @RequestMapping(value = "unionpay/prepayOrder")
    public synchronized @ResponseBody
    ResultTransport unionpayPrepayOrder(
        @RequestParam(required = true, value = "passengerId") Long passengerId,
        @RequestParam(required = true, value = "gsId") Long gsId,
        @RequestParam(required = true, value = "gasNum") String gasNum,
        @RequestParam(required = false, value = "compressorGun") String compressorGun,
        @RequestParam(required = true, value = "money") BigDecimal money,
        @RequestParam(required = true, value = "realMoney") BigDecimal realMoney,
        @RequestParam(required = true, value = "discountMoney") BigDecimal discountMoney,
        @RequestParam(required = false, value = "couponId") Long couponId, String appKey,
        String token, String timestamp, HttpServletResponse response, HttpServletRequest request) {

        List<String> params = new LinkedList<String>();
        params.add(String.valueOf(passengerId));
        params.add(String.valueOf(gsId));
        params.add(String.valueOf(gasNum));
        params.add(String.valueOf(money));
        params.add(String.valueOf(realMoney));
        params.add(String.valueOf(discountMoney));
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        GasStation gasStation = gasStationService.queryById(gsId);
        if (null == gasStation) {
            return ResultTransport.getErrorBy(ErrorConstant.GASSTATION_NOT_EXISTS);
        }

        Passenger passenger = memberService.findOnePassenger(passengerId);
        if (null == passenger) {
            return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
        }

        try {

            OrderTemp orderTemp = new OrderTemp();
            orderTemp.setDiscountMoney(discountMoney);
            orderTemp.setGsId(gasStation.getId());
            orderTemp.setGsName(gasStation.getName());
            orderTemp.setGsServiceNo(gasStation.getServiceNo());
            orderTemp.setGasNum(gasNum);
            orderTemp.setCompressorGun(compressorGun);
            orderTemp.setMoney(money);
            orderTemp.setPassengerId(passenger.getId());
            orderTemp.setPassengerName(passenger.getName());
            orderTemp.setPassengerPhone(passenger.getPhone());
            orderTemp.setPayType(OrderTemp.PayType.unionpay);
            orderTemp.setRealMoney(realMoney);
            orderTemp.setCouponId(couponId);

            Result<OrderTemp> result = gasStationService.paymentOrderTemp(orderTemp);

            if (result.isSuccess()) {
                Setting setting = settingUtils.get();
                // 从classpath加载acp_sdk.properties文件
                SDKConfig.getConfig().loadPropertiesFromSrc(setting);

                String orderId = DemoBase.getOrderId();
                int paymoney = realMoney.multiply(new BigDecimal(100))
                    .intValue(); // txnAmt以'元'为单位,乘以100以'分'为单位传给银联
                String txnTime = DemoBase.getCurrentTime(); // 交易时间
                String merId = setting.getMerId(); // 获取商户号
                Map<String, String> contentData = new HashMap<String, String>();

                /*** 银联全渠道系统，产品参数，除了encoding自行选择外其他不需修改 ***/
                contentData.put("version", "5.1.0"); // 版本号 全渠道默认值
                contentData.put("encoding", "UTF-8"); // 字符集编码 可以使用UTF-8,GBK两种方式
                contentData.put("signMethod", "01"); // 签名方法
                contentData.put("txnType", "01"); // 交易类型 01:消费
                contentData.put("txnSubType", "01"); // 交易子类 01：消费
                contentData.put("bizType", "000201"); // 填写000201
                contentData.put("channelType", "08"); // 渠道类型 08手机

                /*** 商户接入参数 ***/
                contentData.put("merId", merId); // 商户号码，请改成自己申请的商户号或者open上注册得来的777商户号测试
                contentData.put("accessType", "0"); // 接入类型，商户接入填0 ，不需修改（0：直连商户， 1： 收单机构
                // 2：平台商户）
                contentData.put("orderId", orderId); // 商户订单号，8-40位数字字母，不能含“-”或“_”，可以自行定制规则
                contentData.put("txnTime",
                    txnTime); // 订单发送时间，取系统时间，格式为YYYYMMDDhhmmss，必须取当前时间，否则会报txnTime无效
                contentData.put("accType", "01"); // 账号类型 01：银行卡02：存折03：IC卡帐号类型(卡介质)
                contentData.put("txnAmt", String.valueOf(paymoney)); // 交易金额 单位为分，不能带小数点
                contentData.put("currencyCode", "156"); // 境内商户固定 156 人民币

                String out_trade_no = "jyz_af_" + result.getResult().getId();
                contentData.put("reqReserved", out_trade_no);
                String backUrl = "";
                if (setting.getWebUrl().endsWith("/")) {
                    backUrl = setting.getWebUrl()
                        + "passenger/api/rest/v4/gasstation/unionpay/payOrderNotify";
                } else {
                    backUrl = setting.getWebUrl() + "/"
                        + "passenger/api/rest/v4/gasstation/unionpay/payOrderNotify";
                }
                contentData.put("backUrl", backUrl);

                Map<String, String> reqData = AcpService.sign(contentData,
                    DemoBase.encoding); // 报文中certId,signature的值是在signData方法中获取并自动赋值的，只要证书配置正确即可。
                String requestAppUrl = SDKConfig.getConfig()
                    .getAppRequestUrl(); // 交易请求url从配置文件读取对应属性文件acp_sdk.properties中的
                // acpsdk.backTransUrl
                Map<String, String> rspData = AcpService.post(reqData, requestAppUrl,
                    DemoBase.encoding); // 发送请求报文并接受同步应答（默认连接超时时间30秒，读取返回结果超时时间30秒）;这里调用signData之后，调用submitUrl之前不能对submitFromData中的键值对做任何修改，如果修改会导致验签不通过

                if (!rspData.isEmpty()) {
                    if (AcpService.validate(rspData, DemoBase.encoding)) {
                        LogUtil.writeLog("验证签名成功");
                        String respCode = rspData.get("respCode");
                        if (("00").equals(respCode)) {
                            String tn = rspData.get("tn");
                            ResultTransport transport = ResultTransport
                                .getErrorBy(ErrorConstant.SUCCESS);
                            transport.setData(tn);
                            return transport;
                        } else {
                            return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
                        }
                    } else {
                        LogUtil.writeErrorLog("验证签名失败");
                        return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
                    }
                } else {
                    LogUtil.writeErrorLog("未获取到返回报文或返回http状态码非200");
                    return ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
                }
            } else {
                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
                return instance;
            }
        } catch (Exception e) {
            e.printStackTrace();
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
            return instance;
        }

    }

    // 银联支付后回调接口
    @RequestMapping("unionpay/payOrderNotify")
    public synchronized @ResponseBody
    void unionpayPayOrderNotify(HttpServletResponse resp,
        HttpServletRequest req) throws Exception {
        try {
            LogUtil.writeLog("BackRcvResponse接收后台通知开始");

            String encoding = req.getParameter(SDKConstants.param_encoding);
            // 获取银联通知服务器发送的后台通知参数
            Map<String, String> reqParam = getAllRequestParam(req);

            LogUtil.printRequestLog(reqParam);

            Map<String, String> valideData = null;
            if (null != reqParam && !reqParam.isEmpty()) {
                Iterator<Entry<String, String>> it = reqParam.entrySet().iterator();
                valideData = new HashMap<String, String>(reqParam.size());
                while (it.hasNext()) {
                    Entry<String, String> e = it.next();
                    String key = (String) e.getKey();
                    String value = (String) e.getValue();

                    valideData.put(key, value);
                }
            }

            // 重要！验证签名前不要修改reqParam中的键值对的内容，否则会验签不过
            if (!AcpService.validate(valideData, encoding)) {
                LogUtil.writeLog("验证签名结果[失败].");
                // 验签失败，需解决验签问题
            } else {
                LogUtil.writeLog("验证签名结果[成功].");

                LogUtil.writeLog("后台通知的数据orderId:" + valideData.get("orderId"));
                String respCode = valideData.get("respCode");

                if ("00".equals(respCode)) {
                    String out_trade_no = valideData.get("reqReserved"); // 获取后台通知的数据，其他字段也可用类似方式获取
                    Long orderTempId = Long.valueOf(out_trade_no.split("_")[2]);

                    OrderTemp orderTemp = gasStationService.findOneOrderTemp(orderTempId);
                    if (!orderTemp.getStatus().equals(OrderTemp.status_finish)) {
                        Order order = new Order();
                        order.setDiscountMoney(orderTemp.getDiscountMoney());
                        order.setGsId(orderTemp.getGsId());
                        order.setGsName(orderTemp.getGsName());
                        order.setGsServiceNo(orderTemp.getGsServiceNo());
                        order.setGasNum(orderTemp.getGasNum());
                        order.setCompressorGun(orderTemp.getCompressorGun());
                        order.setMoney(orderTemp.getMoney());
                        order.setPassengerId(orderTemp.getPassengerId());
                        order.setPassengerName(orderTemp.getPassengerName());
                        order.setPassengerPhone(orderTemp.getPassengerPhone());
                        order.setPayType(Order.PayType.unionpay);
                        order.setRealMoney(orderTemp.getRealMoney());
                        order.setCouponId(orderTemp.getCouponId());

                        Passenger passenger = memberService
                            .findOnePassenger(orderTemp.getPassengerId());

                        Result<Order> result = gasStationService.paymentOrder(order, passenger);

                        if (result.isSuccess()) {

                            if (null != passenger) {
                                GasRebateEvent gasRebateEvent = new GasRebateEvent(passenger,
                                    result.getResult(),
                                    order.getRealMoney());
                                applicationEventMulticaster.multicastEvent(gasRebateEvent);
                            }

                            Result<OrderTemp> result2 = gasStationService
                                .orderTempTreament(orderTempId);

                            if (result2.isSuccess()) {
                                // 返回给银联服务器http 200 状态码
                                resp.getWriter().print("ok");
                            }
                        }
                    }

                }

            }
            LogUtil.writeLog("BackRcvResponse接收后台通知结束");

        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    // 翼支付支付前接口
    @RequestMapping(value = "bestpay/prepayOrder")
    public synchronized @ResponseBody
    ResultTransport bestpayPrepayOrder(
        @RequestParam(required = true, value = "passengerId") Long passengerId,
        @RequestParam(required = true, value = "gsId") Long gsId,
        @RequestParam(required = true, value = "gasNum") String gasNum,
        @RequestParam(required = false, value = "compressorGun") String compressorGun,
        @RequestParam(required = true, value = "money") BigDecimal money,
        @RequestParam(required = true, value = "realMoney") BigDecimal realMoney,
        @RequestParam(required = true, value = "discountMoney") BigDecimal discountMoney,
        @RequestParam(required = false, value = "couponId") Long couponId, String appKey,
        String token, String timestamp, HttpServletResponse response, HttpServletRequest request) {

        List<String> params = new LinkedList<String>();
        params.add(String.valueOf(passengerId));
        params.add(String.valueOf(gsId));
        params.add(String.valueOf(gasNum));
        params.add(String.valueOf(money));
        params.add(String.valueOf(realMoney));
        params.add(String.valueOf(discountMoney));
        params.add(timestamp);
        params.add(appKey);

        if (!SecurityUtils.checkToken(params, token)) {
            return ResultTransport.getErrorBy(ErrorConstant.TOKEN_ERROR);
        }

        GasStation gasStation = gasStationService.queryById(gsId);
        if (null == gasStation) {
            return ResultTransport.getErrorBy(ErrorConstant.GASSTATION_NOT_EXISTS);
        }

        Passenger passenger = memberService.findOnePassenger(passengerId);
        if (null == passenger) {
            return ResultTransport.getErrorBy(ErrorConstant.MEMBER_NOT_EXISTS_ERROR);
        }

        try {

            OrderTemp orderTemp = new OrderTemp();
            orderTemp.setDiscountMoney(discountMoney);
            orderTemp.setGsId(gasStation.getId());
            orderTemp.setGsName(gasStation.getName());
            orderTemp.setGsServiceNo(gasStation.getServiceNo());
            orderTemp.setGasNum(gasNum);
            orderTemp.setCompressorGun(compressorGun);
            orderTemp.setMoney(money);
            orderTemp.setPassengerId(passenger.getId());
            orderTemp.setPassengerName(passenger.getName());
            orderTemp.setPassengerPhone(passenger.getPhone());
            orderTemp.setPayType(OrderTemp.PayType.alipay);
            orderTemp.setRealMoney(realMoney);
            orderTemp.setCouponId(couponId);

            Result<OrderTemp> result = gasStationService.paymentOrderTemp(orderTemp);

            if (result.isSuccess()) {
                Setting setting = settingUtils.get();
                String callBackUrl = setting.getWebUrl()
                    + "/passenger/api/rest/v4/gasstation/bestpay/payOrderNotify";
                String createUrl = "https://webpaywg.bestpay.com.cn/order.action";

                // 获取商户信息
                String mch_id = setting.getMerchantId();
                String mch_key = setting.getMerKey();
                String mch_pwd = setting.getMchPwd();
                String riskInfo = setting.getRiskcontrolinfo();
                String attach_order_id =
                    "jyz_af_" + result.getResult().getId(); // 商户订单号,这里作为附加信息，因为订单不能个包含特殊字符
                String body = "加油订单付费";

                // 使用随机数来作为订单流水号
                String currTime = TenpayUtil.getCurrTime();
                String strTime = currTime.substring(8, currTime.length()); // 8位日期
                String strRandom = TenpayUtil.buildRandom(6) + ""; // 四位随机数
                String strReq = strTime + strRandom; // 10位序列号,可以自行调整

                String phone = passenger.getPhone();

                // 格式化金额0.00
                DecimalFormat myformat = new java.text.DecimalFormat("0.00");
                String money_ = myformat.format(realMoney);

                // 订单模型
                String total_fee = String
                    .valueOf(money.multiply(new BigDecimal(100)).intValue()); // 元转分
                BestPayOrderModel orderModel = new BestPayOrderModel();
                orderModel.setATTACH(attach_order_id);
                orderModel.setCITYCODE("");
                orderModel.setDIVDETAILS("");
                orderModel.setENCODE("");
                orderModel.setENCODETYPE("1");
                orderModel.setKEY(mch_key);
                orderModel.setLOGINNO("");
                orderModel.setMERCHANTID(mch_id);
                orderModel.setORDERAMT(total_fee); // 分
                orderModel.setORDERCCY("RMB");
                orderModel.setORDERREQTIME(currTime);
                orderModel.setORDERREQTRANSEQ(strReq);
                orderModel.setORDERSEQ(strReq);
                orderModel.setPRODUCTDESC(body);
                orderModel.setPRODUCTID("04");
                orderModel.setPROVINCECODE("");
                orderModel.setRISKCONTROLINFO(riskInfo);
                orderModel.setSERVICECODE("05");
                orderModel.setSESSIONKEY("");
                orderModel.setSUBMERCHANTID("");
                orderModel.setTRANSCODE("01");
                boolean rs = BestPayCreateOrder.createByApp(createUrl, orderModel);

                // 下单失败
                if (!rs) {
                    return ResultTransport.getErrorBy(ErrorConstant.BESTPAY_APP_CREATE_ORDER_ERR);
                }

                // 签名参数
                StringBuffer md5Buffer = new StringBuffer();
                md5Buffer.append("SERVICE=").append("mobile.security.pay").append("&MERCHANTID=")
                    .append(mch_id).append("&MERCHANTPWD=").append(mch_pwd)
                    .append("&SUBMERCHANTID=")
                    .append("").append("&BACKMERCHANTURL=").append(callBackUrl).append("&ORDERSEQ=")
                    .append(strReq).append("&ORDERREQTRANSEQ=").append(strReq).append("&ORDERTIME=")
                    .append(currTime).append("&ORDERVALIDITYTIME=").append("").append("&CURTYPE=")
                    .append("RMB").append("&ORDERAMOUNT=").append(money_).append("&SUBJECT=")
                    .append(body)
                    .append("&PRODUCTID=").append("04").append("&PRODUCTDESC=").append(body)
                    .append("&CUSTOMERID=").append(phone).append("&SWTICHACC=").append("true")
                    .append("&KEY=").append(mch_key);

                // 签名
                logger.info("MAC(MD5)--before--String：" + md5Buffer.toString());
                String sign = CryptTool.md5Digest(md5Buffer.toString());
                logger.info("MAC(MD5)--after--String:" + sign);

                // 拼接返回数据串
                StringBuffer paramsBuffer = new StringBuffer();
                paramsBuffer
                    .append("SERVICE=")
                    .append("mobile.security.pay")
                    .append("&MERCHANTID=")
                    .append(mch_id)
                    // 签约商户号
                    .append("&MERCHANTPWD=").append(mch_pwd).append("&SUBMERCHANTID=").append("")
                    .append("&BACKMERCHANTURL=").append(callBackUrl).append("&SIGNTYPE=")
                    .append("MD5")
                    .append("&SIGN=").append(sign).append("&ORDERSEQ=").append(strReq)
                    .append("&ORDERREQTRANSEQ=").append(strReq).append("&ORDERTIME=")
                    .append(currTime)
                    .append("&ORDERVALIDITYTIME=").append("").append("&ORDERAMOUNT=").append(money_)
                    .append("&CURTYPE=").append("RMB").append("&PRODUCTID=").append("04")
                    .append("&PRODUCTDESC=").append(body).append("&PRODUCTAMOUNT=").append(money_)
                    .append("&ATTACHAMOUNT=").append("0.00").append("&ATTACH=")
                    .append(attach_order_id)
                    .append("&DIVDETAILS=").append("").append("&ACCOUNTID=").append("")
                    .append("&CUSTOMERID=").append(phone).append("&USERIP=").append("")
                    .append("&BUSITYPE=").append("04").append("&SWTICHACC=").append("true")
                    .append("&SUBJECT=").append(body);

                // 返回数据
                String paramList = paramsBuffer.toString();
                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SUCCESS);
                instance.setData(paramList);
                return instance;
            } else {
                ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
                return instance;
            }

        } catch (Exception e) {
            e.printStackTrace();
            ResultTransport instance = ResultTransport.getErrorBy(ErrorConstant.SERVER_ERROR);
            return instance;
        }
    }

    // 翼支付支付后的接口
    @RequestMapping(value = "bestpay/payOrderNotify")
    public synchronized @ResponseBody
    String bestpayPayOrderNotify(HttpServletResponse response,
        HttpServletRequest request) throws UnsupportedEncodingException {

        try {
            // 准备
            request.setCharacterEncoding("UTF-8");
            response.setCharacterEncoding("UTF-8");
            PrintWriter out = response.getWriter();

            // 获取回调数据，注释部分为没有使用的部分数据，其所代表的意义详见翼支付APP文档
            String UPTRANSEQ = request.getParameter("UPTRANSEQ");
            String MERCHANTID = request.getParameter("MERCHANTID");
            String TRANDATE = request.getParameter("TRANDATE");
            String RETNCODE = request.getParameter("RETNCODE");
            String RETNINFO = request.getParameter("RETNINFO");
            // String ORDERREQTRANSEQ = request.getParameter("ORDERREQTRANSEQ");
            String ORDERSEQ = request.getParameter("ORDERSEQ");
            String ORDERAMOUNT = request.getParameter("ORDERAMOUNT");
            // String PRODUCTAMOUNT = request.getParameter("PRODUCTAMOUNT");
            // String ATTACHAMOUNT = request.getParameter("ATTACHAMOUNT");
            // String CURTYPE = request.getParameter("CURTYPE");
            // String ENCODETYPE = request.getParameter("ENCODETYPE");
            // String BANKID = request.getParameter("BANKID");
            String ATTACH = request.getParameter("ATTACH");
            // String UPREQTRANSEQ = request.getParameter("UPREQTRANSEQ");
            // String UPBANKTRANSEQ = request.getParameter("UPBANKTRANSEQ");
            // String PRODUCTNO = request.getParameter("PRODUCTNO");
            String SIGN = request.getParameter("SIGN");

            // 验证签名
            Setting setting = settingUtils.get();
            String key = setting.getMerKey();
            String signStr = "UPTRANSEQ=" + UPTRANSEQ + "&MERCHANTID=" + MERCHANTID + "&ORDERSEQ="
                + ORDERSEQ + "&ORDERAMOUNT=" + ORDERAMOUNT + "&RETNCODE=" + RETNCODE + "&RETNINFO="
                + RETNINFO + "&TRANDATE=" + TRANDATE + "&KEY=" + key;
            String localSign = CryptTool.md5Digest(signStr);

            // 验签失败
            if (!localSign.equals(SIGN)) {
                out.write("UPTRANSEQ_" + UPTRANSEQ);
                logger.info("支付回调，验签失败！");
                return "success";
            }

            // 验签成功，看是否支付成功("0000为成功，其他均为失败")
            if (RETNCODE.equals("0000")) {

                Long orderTempId = Long.valueOf(ATTACH.split("_")[2]);
                OrderTemp orderTemp = gasStationService.findOneOrderTemp(orderTempId);
                if (orderTemp.getStatus().equals(OrderTemp.status_finish)) {
                    return "success";
                }

                Order order = new Order();
                order.setDiscountMoney(orderTemp.getDiscountMoney());
                order.setGsId(orderTemp.getGsId());
                order.setGsName(orderTemp.getGsName());
                order.setGsServiceNo(orderTemp.getGsServiceNo());
                order.setGasNum(orderTemp.getGasNum());
                order.setCompressorGun(orderTemp.getCompressorGun());
                order.setMoney(orderTemp.getMoney());
                order.setPassengerId(orderTemp.getPassengerId());
                order.setPassengerName(orderTemp.getPassengerName());
                order.setPassengerPhone(orderTemp.getPassengerPhone());
                order.setPayType(Order.PayType.bestpay);
                order.setRealMoney(orderTemp.getRealMoney());
                order.setCouponId(orderTemp.getCouponId());

                Passenger passenger = memberService.findOnePassenger(orderTemp.getPassengerId());

                Result<Order> result = gasStationService.paymentOrder(order, passenger);

                if (result.isSuccess()) {

                    if (null != passenger) {
                        GasRebateEvent gasRebateEvent = new GasRebateEvent(passenger,
                            result.getResult(),
                            order.getRealMoney());
                        applicationEventMulticaster.multicastEvent(gasRebateEvent);
                    }

                    Result<OrderTemp> result2 = gasStationService.orderTempTreament(orderTempId);

                    if (result2.isSuccess()) {
                        return "success";
                    } else {
                        return "fail";
                    }

                } else {
                    return "fail";
                }
            }
            return "fail";
        } catch (Exception e) {
            // 异常不返回，以便不丢失支付数据
            e.printStackTrace();
            return "fail";
        }
    }
}
